package com.autumn.platform.dao.schema.mapper.batch;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.transaction.annotation.Transactional;

import com.autumn.platform.dao.annotation.BatchParam;
import com.autumn.platform.dao.annotation.Execute;
import com.autumn.platform.dao.annotation.Executes;
import com.autumn.platform.dao.annotation.SqlRef;
import com.autumn.platform.dao.schema.mapper.EnumParam;
import com.autumn.platform.dao.schema.mapper.EnumParamItem;
import com.autumn.platform.dao.schema.mapper.ParamDefine;

@Mapper
public interface BatchDao {

    public ParamDefine selectParamDefine(@Param("paramCode") String paramCode);

    public List<EnumParamItem> selectEnumParamItems(@Param("paramCode") String paramCode);

    public int deleteEnumParamItems(@Param("paramCode") String paramCode);

    /** ===========单一SQL，不同参数多次执行=============== **/
    //单一SQL，每次执行参数不同
    @SqlRef("insertEnumParamItems")
    public int[] batchSingleSql1(@BatchParam List<EnumParamItem> items);

    //单一SQL，每次执行参数不同，参数从对象中的一个属性取值
    @SqlRef("insertEnumParamItems")
    public int[] batchSingleSql2(@BatchParam(property = "items") EnumParam enumParam);

    //单一SQL，每次执行参数不同，参数由普通参数和批量参数组成
    @SqlRef("insertEnumParamItems2")
    public int[] batchSingleSql3(@Param("paramCode") String paramCode, @BatchParam(name = "item", index = "index") List<EnumParamItem> items);

    /** ===========多SQL=============== **/
    //多SQL，含有BatchParam注解，每个SQL执行时参数各不相同
    @SqlRef({"insertParamDefine2", "insertEnumParamItems"})
    public int[] batchMultiSql(@Param("paramCode") String paramCode, @BatchParam(name = "item", index = "index", oneByOne = true) List<Object> datas);

    //多SQL，不含有BatchParam注解，每个SQL执行时参数完全相同
    @SqlRef({"deleteParamDefine", "deleteEnumParamItems"})
    public int[] batchMultiSqlButSingleParam(@Param("paramCode") String paramCode);

    //多SQL，不含有BatchParam注解，每个SQL执行时参数完全相同，同时这个参数是一个数组类型
    @SqlRef({"deleteMultiParamDefine", "deleteMultiEnumParamItems"}) //多SQL单参数，且每个SQL执行时参数完全相同，同时这个参数是一个数组类型
    public int[] batchMultiSqlButSingleParam(@Param("paramCodes") String[] paramCodes);

    /** ===========混合批量=============== **/

    // 混合批量，其中子SQL可能是批量，也可能不是批量
    @Executes({
            @Execute(sqlRef = "insertParamDefine", batch = false, property = "param"),
            @Execute(sqlRef = "insertEnumParamItems", name = "item", property = "items")
    })
    public int[] compositeBatch(@Param("param") ParamDefine paramDefine, @Param("items") List<EnumParamItem> items);

    // 混合批量，其中每一个子SQL又是一个批量
    @Executes({
            @Execute(sqlRef = "deleteParamDefine", name = "paramCode"),
            @Execute(sqlRef = "deleteEnumParamItems", name = "paramCode")
    })
    public int[] compositeBatch2(String[] paramCodes);

    /**
     * <pre>
     * 首先整个参数封装成P{"param":paramDefine, "items":items}的形式 
     * 1. 第一个SQL，是一个普通的执行，参数为P的"param"属性，也就是paramDefine对象
     * 2. 第二个SQL，也是一个普通的执行，但是参数为P的"param.paramCode"属性，也就是paramDefine对象的paramCode属性
     * 3. 第三个SQL，是一个单SQL执行多次的批量，其中每次执行的批量参数为{"param":paramDefine, "index": index, "item":items(index)}
     * </pre>
     */
    @Transactional
    @Executes({
            @Execute(sqlRef = "updateParamDefine", batch = false, property = "param"),
            @Execute(sqlRef = "deleteEnumParamItems", batch = false, property = "param.paramCode"),
            @Execute(sqlRef = "insertEnumParamItems", name = "item", property = "items")
    })
    public int[] compositeBatch3(@Param("param") ParamDefine paramDefine, @Param("items") List<EnumParamItem> items);

}
